/**
 *  Copyright (C) 2008-2013  Telosys project org. ( http://www.telosys.org/ )
 *
 *  Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *          http://www.gnu.org/licenses/lgpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.telosys.persistence;

import org.telosys.common.TelosysRuntimeException;
import org.telosys.common.logger.TelosysClassLogger;
import org.telosys.persistence.database.DatabaseManager;
import org.telosys.persistence.env.PersistenceInitializer;
import org.telosys.persistence.impl.PersistenceManagerFactoryImpl;

/**
 * Persistence bootstrap methods
 *  
 * @author Laurent Guerin
 *
 */
public class TelosysPersistence 
{
    private static final TelosysClassLogger log  = new TelosysClassLogger(TelosysPersistence.class, true);

	// JPA
//	public final static RecordManagerFactory createRecordManagerFactory(String persistenceUnitName)
//	{
//		
//	}
	
	private static PersistenceManagerFactory[] factories = null ; // All the existing factories
	
	private final static void initPersistenceManagerFactories()
	{
		int n = DatabaseManager.getNumberOfDatabases();
		log.trace("initPersistenceManagerFactories() nb databases = " + n ) ;
		factories = new PersistenceManagerFactory[n];
		for ( int i = 0 ; i < n ; i++ )
		{
			factories[i] = null ;
		}
	}
	
	private final static void checkInit()
	{
		if ( factories == null ) 
		{
			// Not yet initialized 
			try {
				PersistenceInitializer.initFromClassPath();
			} catch (Exception e) {
				throw new TelosysRuntimeException("Cannot initialize Telosys-Persistence from ClassPath", e );
			}
			initPersistenceManagerFactories();
		}
	}
	
	/**
	 * Returns the PersistenceManagerFactory for the given database id.<br>
	 * ( launch the Initialization if necessary )
	 * @param databaseId
	 * @return
	 */
	public final static PersistenceManagerFactory getPersistenceManagerFactory(int databaseId)
	{
		checkInit();
		return getOrCreateFactory( databaseId);
	}

	
	/**
	 * Returns the PersistenceManagerFactory for the default database.<br>
	 * ( launch the Initialization if necessary )
	 * @return
	 */
	public final static PersistenceManagerFactory getPersistenceManagerFactory()
	{
		checkInit();
		return getOrCreateFactory( DatabaseManager.getDefaultDatabase() );
	}

	/**
	 * Returns the id of the default database.<br>
	 * ( launch the Initialization if necessary )
	 * @return
	 */
	public final static int getDefaultDatabaseId()
	{
		checkInit();
		return DatabaseManager.getDefaultDatabase() ;
	}

	/**
	 * Returns the number of databases slots (including void slots).<br>
	 * ( launch the Initialization if necessary )
	 * @return 
	 */
	public final static int getNumberOfDatabaseSlots()
	{
		checkInit();
		return factories.length ;
	}
	
	private final static PersistenceManagerFactory getOrCreateFactory(int databaseId)
	{
		if ( databaseId >= 0 && databaseId < factories.length ) 
		{
			PersistenceManagerFactory factory = factories[databaseId] ;
			if ( factory != null ) {
				return factory ;
			}
			else {
				factory = new PersistenceManagerFactoryImpl(databaseId);
				factories[databaseId] = factory ;
				return factory ;
			}
		}
		else 
		{
			throw new TelosysRuntimeException("Cannot create factory, invalid database id " + databaseId );
		}
	}
	
}
